package com.ts.graphql.client;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.*;

/**
 *
 * 将 对象 转为 GraphQL 的请求参数的工具类
 *
 * @author suyi
 */
final class GraphQlParamsConverter {

    private GraphQlParamsConverter() {}

    /**
     * 将 对象 转为 GraphQL 的请求参数
     * @param object 对象参数
     * @return  GraphQL 请求参数
     */
    static String objectToGraphQLParamsString(Object object) {
        JSONObject jsonObject = (JSONObject) JSON.toJSON(object);
        return mapToGraphQLParamsString(jsonObject);
    }


    /**
     * 将 Map 转为 GraphQL 的请求参数
     * @param map   map
     * @return      GraphQL 的请求参数
     */
    static String mapToGraphQLParamsString(Map<String, Object> map) {

        if (map.isEmpty()) {
            return "";
        }

        StringJoiner stringJoiner = new StringJoiner(", ");

        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            String keyValue = entryToKeyValueGraphString(entry);
            if (keyValue == null) {
                continue;
            }
            stringJoiner.add(keyValue);
        }

        return stringJoiner.toString();
    }

    /**
     * 将 Map.Entry 转为 GraphQL 风格的键值对字符串
     * GraphQL风格 key : value
     * JSON风格    "key" : value
     *
     * @param   entry entry
     * @return  GraphQL 风格的键值对字符串
     */
    private static String entryToKeyValueGraphString(Map.Entry<String, Object> entry) {
        Object value = entry.getValue();
        if (value == null) {
            return null;
        }
        StringBuilder keyValueBuilder = new StringBuilder();
        keyValueBuilder.append(entry.getKey());
        keyValueBuilder.append(": ");
        handleValue(value, keyValueBuilder);
        return keyValueBuilder.toString();
    }

    /**
     * 不同类型的 value 有不同的处理方式
     * @param value             Entry 的值
     * @param keyValueBuilder   keyValueBuilder
     */
    private static void handleValue(Object value, StringBuilder keyValueBuilder) {
        if (value instanceof NullKey) {
            keyValueBuilder.append(value);
        }
        if (value instanceof String) {
            keyValueBuilder.append("\"").append(value).append("\"");
        } else if (value instanceof Number || value instanceof Boolean) {
            keyValueBuilder.append(value);
        } else if (value instanceof Collection) {
            keyValueBuilder.append("[");
            StringJoiner joiner = new StringJoiner(",");
            Collection<?> collection = (Collection<?>) value;
            for (Object element : collection) {
                StringBuilder elementStringBuilder = new StringBuilder();
                handleValue(element, elementStringBuilder);
                joiner.add(elementStringBuilder);
            }
            keyValueBuilder.append(joiner);
            keyValueBuilder.append("]");
        } else {
            keyValueBuilder.append("{");
            // 若 value 为 Object，
            // 转为 JSONObject (Map<String, Object> 的子类)，继续向下转化
            keyValueBuilder.append(objectToGraphQLParamsString(value));
            keyValueBuilder.append("}");
        }
    }

}
